﻿#include "ssActorMgr.h"


namespace StarSeeker
{

ssActorMgr::ssActorMgr()
{
	m_iDAlloter.Init();
}

ssActorMgr::~ssActorMgr()
{
	Clear();
}

void ssActorMgr::CreatWorkThreads(u32 count)
{
	if (m_threads.Count() == 0 && count < 1024)
	{
		m_threads.PushBack(new ssActorThread(*this));
	}
}

u32 ssActorMgr::AddActor(ssActor* pActor)
{
	m_lock.Lock();
	pActor->m_id = m_iDAlloter.GetID();
	pActor->m_enabled = 1;
	m_allActor.insert(pair<u32, ssActor*>(pActor->m_id, pActor));
	m_lock.Unlock();
	return pActor->m_id;
}

void ssActorMgr::DiscardActor(u32 actorID)
{
	m_lock.Lock();
	map<u32, ssActor*>::iterator itr = m_allActor.find(actorID);
	if (itr != m_allActor.end())
	{
		itr->second->m_enabled = false;
		m_discardList.PushBack(itr->second);
	}
	m_lock.Unlock();
}

bool ssActorMgr::PostMsg(bool isNotify, u32 actorID, ssMsg_s &m)
{
	bool ret = false;
	m_lock.Lock();
	map<u32, ssActor*>::iterator itr = m_allActor.find(actorID);
	if (itr != m_allActor.end() && itr->second->m_enabled==1)
	{
		itr->second->PushMsg(m);
		ret = true;
	}
	m_lock.Unlock();
	if (ret)
	{
		SS_MUTEX_LOCK(m_mutex);
		m_pendingList.PushBack(actorID);
		if (isNotify)
		{
			NotifyOneWorker(); //通知可以读取数据
		}
		SS_MUTEX_UNLOCK(m_mutex);
	}
	return ret;
}

bool ssActorMgr::PostMsg(bool isNotify, u32 actorID, u32 msgID, u32 subID, ulint param1, ulint param2, ulint param3)
{
	ssMsg_s m = { msgID, subID, param1, param2, param3 };
	return PostMsg(isNotify, actorID, m);
}

void ssActorMgr::Clear()
{
	Exit();

	SS_MUTEX_LOCK(m_mutex);
	m_pendingList.Clear();
	SS_MUTEX_UNLOCK(m_mutex);
	m_lock.Lock();
	map<u32, ssActor*>::iterator itr;
	for (itr=m_allActor.begin(); itr != m_allActor.end(); ++itr)
	{
		delete itr->second;
	}
	m_allActor.clear();
	m_lock.Unlock();
}

void ssActorMgr::DeleteActor()
{
	m_lock.Lock();
	ssList<ssActor*>::Iterator dit = m_discardList.Begin();
	while (dit.IsVaild())
	{
		if ((*dit)->GetMsgCount()==0 && !(*dit)->IsWorking())
		{
			m_allActor.erase((*dit)->m_id);
			delete (*dit);
			dit = m_discardList.EraseItr(dit);
		}
		else
		{
			++dit;
		}
	}
	m_lock.Unlock();
}

StarSeeker::ssActor* ssActorMgr::PopPendingActor()
{
	u32 id = 0;
	ssActor* ret = 0;

	//SS_MUTEX_LOCK(m_mutex);
	m_pendingList.PopFront(&id);
	//SS_MUTEX_UNLOCK(m_mutex);
	if (id)
	{
		m_lock.Lock();
		map<u32, ssActor*>::iterator itr = m_allActor.find(id);
		if (itr != m_allActor.end())
		{
			ret = itr->second;
		}
		m_lock.Unlock();
	}

	return ret;
}

StarSeeker::ulint ssActorMgr::GetPendingCount()
{
	return m_pendingList.Count();
}

void ssActorMgr::PushPendingActor(u32 actorID)
{
	//SS_MUTEX_LOCK(m_mutex);
	m_pendingList.PushBack(actorID);
	//SS_MUTEX_UNLOCK(m_mutex);
}

}
